﻿/*
 *  ============================================================================
 *  Name:           Gestão de parques de estacionamento
 *  Author:         João Faria
 *  Email:          a8836@alunos.ipca.pt
 *                  jfaria.gmr@gmail.com
 *  Version:        0
 *  Date:           2013-04-10
 *  Copyright:       
 *  Description:    IPCA - Programação II
 *                  Projecto final
 *  ============================================================================
 */

using System;
using System.Collections.Generic;
using GesParking.BusinessObjects;
using GesParking.DataLayer;
using GesParking.Exceptions;

namespace GesParking.BusinessLayer
{
    /// <summary>
    /// Classe que gere os parques
    /// </summary>
    public class ParksBL
    {
        #region Estado

        ParksDL parks;

        #endregion

        #region Propriedades

        /// <summary>
        /// Propriedade parks
        /// </summary>
        public ParksDL Parks
        {
            get { return parks; }
            set { parks = value; }
        }

        #endregion

        #region construtor

        /// <summary>
        /// Construtor por omissão
        /// </summary>
        public ParksBL()
        {
            parks=new ParksDL();
        }

        #endregion

        #region Métodos da classe

        /// <summary>
        /// Verifica se parque existe
        /// </summary>
        /// <param name="id">Id do parque</param>
        /// <returns>True caso exista, false caso não exista</returns>
        public static bool ExisteParqueBL(Guid id)
        {
            IEnumerator<ParkBo> enu = ParksDL.ListDL().GetEnumerator();
            while (enu.MoveNext())
            {
                if (enu.Current.Id == id)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Verifica se parque existe
        /// </summary>
        /// <param name="p">Parque a verificar</param>
        /// <returns>True caso exista, false caso não exista</returns>
        public static bool ExisteParqueBL(ParkBo p)
        {
            IEnumerator<ParkBo> enu = ParksDL.ListDL().GetEnumerator();
            while ( enu.MoveNext() )
            {
                if (enu.Current==p)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Get parque
        /// </summary>
        /// <param name="id">Id parque</param>
        /// <returns>Parque</returns>
        public static ParkBo Get(Guid id)
        {
            IEnumerator<ParkBo> enu = ParksDL.ListDL().GetEnumerator();
            while (enu.MoveNext())
            {
                if (enu.Current.Activo == true)
                {
                    return (enu.Current);
                }
            }
            throw new ParkNotFoundException(); ;
        }

        #endregion

        #region Métodos

        /// <summary>
        /// Adiciona um novo parque
        /// </summary>
        /// <param name="p">Parque a adicionar</param>
        /// <returns>True caso o parque seja adicionado</returns>
        public bool AddBL (ParkBo p)
        {
            if (ExisteParqueBL(p))
            {
                throw new DuplicateParkException();
            }
            ParksDL.AddDL(p);
            ParksDL.Alterado = true;
            return true;
        }

        /// <summary>
        /// Desactiva um parque
        /// </summary>
        /// <param name="p">Parque a desactivar</param>
        /// <returns>True caso o parque seja desactivado</returns>
        public bool DisableBL(ParkBo p)
        {
            if (!ExisteParqueBL(p))
            {
                throw new ParkNotFoundException();
            }
            ParksDL.DisableDL(p);
            ParksDL.Alterado = true;
            return true;
        }

        /// <summary>
        /// Desactiva um parque
        /// </summary>
        /// <param name="id">Id do parque a desactivar</param>
        /// <returns>True caso o parque seja desactivado</returns>
        public bool DisableBL(Guid id)
        {
            if (!ExisteParqueBL(id))
            {
                throw new ParkNotFoundException();
            }
            IEnumerator<ParkBo> enu = ParksDL.ListDL().GetEnumerator();
            while (enu.MoveNext())
            {
                if (enu.Current.Id == id)
                {
                    enu.Current.Activo = false;
                    ParksDL.Alterado = true;
                }
            }
            return true;
        }

        /// <summary>
        /// Actualiza o nome de um parque
        /// </summary>
        /// <param name="id">Id do parque</param>
        /// <param name="n">Nome do parque</param>
        /// <returns>True caso seja actualizado</returns>
        public bool UpdateParkNameBL(Guid id, string n)
        {
            if (!ExisteParqueBL(id))
            {
                throw new ParkNotFoundException();
            }
            ParksDL.UpdateParkNameDL(id, n);
            ParksDL.Alterado = true;
            return true;
        }

        /// <summary>
        /// Actualiza a capacidade máxima de um parque
        /// </summary>
        /// <param name="id">Id do parque</param>
        /// <param name="n">Capacidade máxima</param>
        /// <returns>True caso seja actualizado</returns>
        public bool UpdateParkMaxLoadBL(Guid id, int n)
        {
            if (!ExisteParqueBL(id))
            {
                throw new ParkNotFoundException();
            }

            if (ParkingRegistryBL.Count(id)>n)
            {
                throw new ChangingNotAllowedException();
            }
            ParksDL.UpdateParkMaxLoadDL(id, n);
            ParksDL.Alterado = true;
            return true;
        }

        /// <summary>
        /// Lista os parques activos
        /// </summary>
        /// <returns>Lista de parques activos</returns>
        public List<ParkBo> ListBL()
        {
            List<ParkBo> list = ParksDL.ListDL();
            IEnumerator<ParkBo> enu = ParksDL.ListDL().GetEnumerator();
            while (enu.MoveNext())
            {
                if (enu.Current.Activo == true)
                {
                    list.Add(enu.Current);
                }
            }
            return list;
        }

        /// <summary>
        /// Grava os dados dos parkes
        /// </summary>
        public void Save()
        {
            /* 
             * Falta tratar erros com acessos e permissões de ficheiros
             */
            ParksDL.Save();
        }

        /// <summary>
        /// Classe que lê os dados dos parques
        public void Read()
        {
            /* 
             * Falta tratar erros com acessos e permissões de ficheiros
             */
            ParksDL.Read();
        }

        #endregion
    }
}
